function p(...msg: any[]) {
    console.log(msg)
}
/**
 * Buffer 容器
 */
class BufferContainer {
    private _buffer: ArrayBuffer;
    private _byteLength = 0;
    private _capacity = 16;
    private _add_size = 16;

    constructor(buff: ArrayBuffer | null = null) {
        if (buff) {
            this._byteLength = buff.byteLength;
            this._capacity = Math.ceil(this._byteLength / this._add_size) * 16
            let tempArrayBuffer = new ArrayBuffer(this._capacity);
            let dst = new Uint8Array(tempArrayBuffer);
            let src = new Uint8Array(buff);
            dst.set(src);
            this._buffer = dst.buffer;
        } else {
            this._buffer = new ArrayBuffer(this._capacity)
        }
    }

    /**
     * @param num 
     */
    pushU8(num: number) {
        let u16 = new Uint8Array([num]);
        this._checkLength(2);
        let u16View = new Uint8Array(this._buffer);
        u16View.set(u16, this._byteLength);
        this._byteLength = this._byteLength + 1;
    }
    /**
     * @param num 
     */
    pushI8(num: number) {
        let u16 = new Int8Array([num]);
        this._checkLength(2);
        let u16View = new Int8Array(this._buffer);
        u16View.set(u16, this._byteLength);
        this._byteLength = this._byteLength + 1;
    }
    /**
     * length必须是2的倍数
     * @param num 
     */
    pushU16(num: number) {
        let u16 = new Uint16Array([num]);
        this._checkLength(2);
        let u16View = new Uint16Array(this._buffer);

        this._must2(this._byteLength);

        u16View.set(u16, this._byteLength / 2);
        this._byteLength = this._byteLength + 2;
    }

    /**
     * length必须是2的倍数
     * @param num 
     */
    pushI16(num: number) {
        let u16 = new Int16Array([num]);
        this._checkLength(2);
        let u16View = new Uint16Array(this._buffer);

        this._must2(this._byteLength);

        u16View.set(u16, this._byteLength / 2);
        this._byteLength = this._byteLength + 2;
    }
    /**
    * @param idx 
    */
    readI8(idx: number) {
        let i8v = new Int8Array(this._buffer);
        return i8v[idx];
    }
    /**
     * @param idx 
     */
    readI16(idx: number) {
        let dv = new DataView(this._buffer);
        let r = dv.getInt16(idx * 2,true)
        return r;
    }
    /**
    * @param idx 
    */
    readU16(idx: number) {
        let dv = new DataView(this._buffer);
        let r = dv.getUint16(idx * 2,true)
        return r;
    }
    /**
     * 设置
     * @param idx 
     */
    setI16(idx: number, num: number) {
        let dv = new DataView(this._buffer);
        dv.setInt16(idx * 2, num);
    }
    _checkLength(size: number) {
        if (this._byteLength + size > this._capacity) {
            let old = this._buffer;
            let oldView = new Uint8Array(old);
            // 扩容
            this._capacity = this._capacity + this._add_size
            this._buffer = new ArrayBuffer(this._capacity)
            let newView = new Uint8Array(this._buffer);
            newView.set(oldView);
        }
    }
    /**
     * 检查num是否2的倍数
     * @param num 
     * @returns true 2的倍数 false 不是2的倍数
     */
    _check2(num: number) {
        let check = num % 2;
        return check == 0
    }
    _must2(num: number) {
        if (!this._check2(num)) {
            throw new Error(`${num}不是2的倍数`)
        }
    }

    get length() {
        return this._byteLength
    }
    get capacity() {
        return this._capacity
    }
    get buffer() {
        return this._buffer
    }
}

class Bytes {
    /**
     * 从高位的offset位开始读取length位
     * @param num 
     * @param offset 
     * @param length 
     */
    static leftBytes(
        num: number,
        offset: number = num.toString().length,
        length: number = num.toString().length,
    ) {
        // 拆分为字节数组
        let numBytes = num.toString(2).split("");

        // 左高位
        let left = offset > numBytes.length
            ? 0
            : numBytes.length - offset;

        // 右低位
        let right = left + length > numBytes.length
            ? numBytes.length
            : left + length;

        return parseInt(numBytes.slice(left, right).join(""), 2);
    }

    /**
     * 从右边读取n位
     */
    static rightBytes(
        num: number,
        offset: number = num.toString().length,
        length: number = num.toString().length
    ) {
        // 拆分为字节数组
        let numBytes = num.toString(2).split("");

        // 右低位
        let right = offset > numBytes.length
            ? 0
            : offset

        // 左高位
        let left = offset + length > numBytes.length
            ? numBytes.length
            : right - length;


        return parseInt(numBytes.slice(left, right).join(""), 2);
    }

    static readBytes(
        num: number,
        offset: number,
        length: number,
        unsigned = true //无符号 有符号
    ) {
        // 拆分为字节数组并倒序
        let numBytes = num.toString(2).split("").reverse();
        // 读取
        if (offset >= numBytes.length) {
            return 0;
        }

        let start = offset > numBytes.length
            ? 0
            : offset;
        let end = start + length > numBytes.length
            ? numBytes.length
            : start + length


        let r = parseInt(numBytes.slice(start, end).reverse().join(""), 2)
        let temp = numBytes.slice(start, end).reverse();

        // 填充长度
        while (temp.length < length) {
            temp.unshift("0")
        }
        if (temp[0] == "1" && unsigned == false) {  //有符号的处理
            r = r - Math.pow(2, length);
        }
        return r;
    }
}
import * as fs from "fs"
function b() {
    let fileBuffer = fs.readFileSync("test.e")
    let buffer = new BufferContainer(fileBuffer);
    // buffer.pushU8(32);
    // let n = 50;
    // for (let i = 0; i < n; i++) {
    //     buffer.pushU8(i);
    // }
    // // console.log("b", buffer)
    // let t = buffer.readI16(0);
    // console.log(t);
    buffer.setI16(0, -2);
    buffer.setI16(1, -1);
    buffer.setI16(2, 0);
    buffer.setI16(3, 1);
    buffer.setI16(4, 2);
    console.log("b", buffer)

    console.log("0", buffer.readI16(0));
    console.log("1", buffer.readI16(1));
    console.log("2", buffer.readI16(2));
    console.log("3", buffer.readI16(3));
    console.log("4", buffer.readI16(4));
    console.log("21", buffer.readI16(21));

    console.log("u---")
    console.log("0", buffer.readU16(0));
    console.log("1", buffer.readU16(1));
    console.log("2", buffer.readU16(2));
    console.log("3", buffer.readU16(3));
    console.log("4", buffer.readU16(4));

    let data = parseInt("111000111011", 2)
    // console.log("data", data, data.toString(2));
    let l = Bytes.leftBytes(data, 13, 13)
    let r = Bytes.readBytes(data, 12 - 3, 3);
    // console.log(r)

    let data16 = parseInt("0000000000000100", 2);
    Bytes.readBytes(data16, 0, 9, false);
}

export {
    BufferContainer,
    Bytes,
    b,
}